package com.qingcloud.adminbackend.utils;

import cn.hutool.core.util.StrUtil;
import com.qingcloud.adminbackend.enums.DatabaseTypeEnum;
import lombok.extern.slf4j.Slf4j;

import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 数据库工具
 *
 * @author wangjinnan
 */
@Slf4j
public class DbUtil {

    private DbUtil() {
    }

    /**
     * 获取数据库jdbc连接url.
     *
     * @param ip               数据库IP
     * @param port             端口
     * @param databaseTypeEnum 数据库类型
     * @param catalog          数据库名称
     * @return jdbc url
     */
    public static String getJdbcUrl(String ip, Integer port, DatabaseTypeEnum databaseTypeEnum, String catalog) {
        try {
            Class.forName(databaseTypeEnum.driver);
        } catch (ClassNotFoundException e) {
            log.error(e.getMessage(), e);
        }
        //不同数据库，url不同组装方式
        if (StrUtil.isBlank(catalog)) {
            catalog = "";
        } else {
            if (databaseTypeEnum.equals(DatabaseTypeEnum.ORACLE)) {
                catalog = ":" + catalog;
            } else if (databaseTypeEnum.equals(DatabaseTypeEnum.SQL_SERVER)) {
                catalog = ";DatabaseName=" + catalog;
            } else {
                catalog = "/" + catalog;
            }

        }
        if (databaseTypeEnum.equals(DatabaseTypeEnum.PGSQL)) {
            return "jdbc:postgresql://" + ip + ":" + port + catalog;
        }
        if (databaseTypeEnum.equals(DatabaseTypeEnum.ORACLE)) {
            return "jdbc:oracle:thin:@" + ip + ":" + port + catalog;
        }
        if (databaseTypeEnum.equals(DatabaseTypeEnum.SQL_SERVER)) {
            return "jdbc:sqlserver://" + ip + ":" + port + catalog;
        }
        return "jdbc:mysql://" + ip + ":" + port + catalog;
    }

    /**
     * 获取指定数据库服务器的所有数据库名称
     *
     * @param ip               IP
     * @param port             端口
     * @param username         用户名
     * @param password         密码
     * @param databaseTypeEnum 数据库类型
     * @return
     */
    public static List<String> getAllCatalog(String ip, Integer port, String username,
                                             String password, DatabaseTypeEnum databaseTypeEnum) {
        final String jdbcUrl = getJdbcUrl(ip, port, databaseTypeEnum, "");
        //获取连接
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(jdbcUrl, username, password);
            List<String> catalogList = new ArrayList<>();
            //获取数据库元数据
            DatabaseMetaData dmd = connection.getMetaData();
            ResultSet catalogs = dmd.getCatalogs();
            while (catalogs.next()) {
                //读取数据库名称
                catalogList.add(catalogs.getString(1));
            }
            return catalogList;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (Objects.nonNull(connection)) {
                try {
                    connection.close();
                } catch (SQLException ex) {
                    log.error(ex.getMessage(), ex);
                }
            }
        }
        return Collections.emptyList();
    }

    /**
     * 获取指定数据库下的所有表和字段名称
     *
     * @param catalog          数据库名称
     * @param ip               IP
     * @param port             端口
     * @param username         用户名
     * @param password         密码
     * @param databaseTypeEnum 数据库类型
     * @return
     */
    public static List<DbColumnInfo> getTableAndColumn(String catalog, String ip, Integer port, String username,
                                                       String password, DatabaseTypeEnum databaseTypeEnum) {
        final String jdbcUrl = getJdbcUrl(ip, port, databaseTypeEnum, "");
        //获取连接
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(jdbcUrl, username, password);
            List<DbColumnInfo> columnInfoList = new ArrayList<>();
            //获取数据库元数据
            DatabaseMetaData dmd = connection.getMetaData();
            //获取所有字段信息
            final ResultSet columns = dmd.getColumns(catalog, null,
                    null, null);
            while (columns.next()) {
                columnInfoList.add(new DbColumnInfo()
                        .setTableName(columns.getString("TABLE_NAME"))
                        .setColumnName(columns.getString("COLUMN_NAME"))
                        .setColumnTypeName(columns.getString("TYPE_NAME")));
            }
            return columnInfoList;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (Objects.nonNull(connection)) {
                try {
                    connection.close();
                } catch (SQLException ex) {
                    log.error(ex.getMessage(), ex);
                }
            }
        }
        return Collections.emptyList();
    }

//    public static void main(String[] args) {
//        getTableAndColumn("wcenter", "58.83.189.133", 3306, "wcenteruser", "Waming@2030", DatabaseTypeEnum.MYSQL);
//    }
}
